iT邦幫忙

2024 iThome 鐵人賽

DAY 30
0
Modern Web

現在就學React.js 系列 第 30

React Redux Toolkit Day30

  • 分享至 

  • xImage
  •  

Redux 是一個狀態管理庫,主要用來管理應用中的全局狀態,特別是當應用變得複雜時。Redux Toolkit(RTK)是官方推薦的開發 Redux 應用的工具集,它大大簡化了 Redux 開發,並幫助減少樣板程式碼的撰寫。

什麼是 Redux Toolkit?

Redux Toolkit 是 Redux 官方提供的一個專門用來簡化 Redux 開發的工具包。它提供了以下核心功能:

  • 簡化 Redux 配置:內建 reducer 組合器和默認配置選項。
  • Thunk:幫助處理非同步邏輯(如 API 請求)的 middleware。
  • 開發工具整合:如 Redux DevTools 。

安裝 Redux Toolkit

在使用 Redux Toolkit 之前,我們需要安裝相應的依賴項目,包括 @reduxjs/toolkitreact-redux

npm install @reduxjs/toolkit react-redux

Redux 核心概念回顧

先簡單回顧 Redux 的核心概念:

  • Store:應用中所有狀態的容器。
  • State:應用當前的狀態。
  • Action:描述狀態變更的 JavaScript 對象。
  • Reducer:接收 action 並更新 state 的函數。
  • Dispatch:將 action 發送到 reducer 的方法。
  • Selector:從 store 中提取資料的函數。

Step 1: 設置 Redux Store

Redux store 是整個應用狀態的容器。使用 Redux Toolkit,我們可以輕鬆創建一個 store:


// store.js
import { configureStore } from '@reduxjs/toolkit';
import counterReducer from './counter/counterSlice';

const store = configureStore({
  reducer: {
    counter: counterReducer,
  },
});

export default store;

使用 configureStore() 來創建 Redux store,它接受一個包含所有 reducer 的對象。

並在創建 counterReducer

Step 2: 創建 Slice

Slice 是 Redux Toolkit 的一個新概念,它將 reducer、action 和 state 全部包裝在一起。每個 slice 都代表應用中的一部分狀態。

我們來創建一個簡單的 counter slice,該 slice 包含一些增加和減少計數器的邏輯。


// features/counter/counterSlice.js
import { createSlice } from '@reduxjs/toolkit';

export const counterSlice = createSlice({
  name: 'counter',
  initialState: {
    value: 0,
  },
  reducers: {
    increment: (state) => {
      state.value += 1;
    },
    decrement: (state) => {
      state.value -= 1;
    },
    incrementByAmount: (state, action) => {
      state.value += action.payload;
    },
  },
});

export const { increment, decrement, incrementByAmount } = counterSlice.actions;

export default counterSlice.reducer;

我們使用了 createSlice(),這個函數會自動生成 action 和 reducer。incrementdecrementincrementByAmount 是我們定義的 action,state.value 是我們要管理的狀態。

Step 3: 提供 Store 給 React

現在,我們需要將 Redux store 提供給整個 React 應用。我們使用 Provider 來將 store 傳遞給 React 組件樹。


// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import store from './store';
import App from './App';

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);

Providerstore 連接到 React 應用中的所有組件,這樣每個組件都能夠訪問全局狀態。

Step 4: 在組件中使用 Redux 狀態

接下來,我們來看看如何在組件中訪問 Redux 狀態並派發 action。

Redux Toolkit 提供了兩個重要的 hook:useSelectoruseDispatch

  • useSelector:用於從 Redux store 中選擇狀態。
  • useDispatch:用於派發 action。

// Counter.js
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement, incrementByAmount } from './features/counter/counterSlice';

function Counter() {
  const count = useSelector((state) => state.counter.value);
  const dispatch = useDispatch();

  return (
    <div>
      <h1>Counter: {count}</h1>
      <button onClick={() => dispatch(increment())}>+</button>
      <button onClick={() => dispatch(decrement())}>-</button>
      <button onClick={() => dispatch(incrementByAmount(5))}>+5</button>
    </div>
  );
}

export default Counter;

我們使用了 useSelector 來從 store 中選擇計數器的 value,並使用 useDispatch 來派發 incrementdecrementincrementByAmount action來更改狀態的值。


看完教學之後,馬來上動手實作看看!今天是要把 Day18 的TodoList小作品做個重構,讓原先用 Redux 的狀態管理改用成Redux ToolKit 吧!同時加深學習印象~那就來實作吧!

1. 安裝 Redux Toolkit 和 React-Redux

npm install @reduxjs/toolkit react-redux

2. 使用 createSlice 定義 Slice

在 Redux Toolkit 中,你可以使用 createSlice 來同時定義 reducer 和 action。這樣可以減少樣板程式碼的撰寫。


// reducers/todoSlice.js
import { createSlice } from '@reduxjs/toolkit'

// 定義初始狀態
const initialState = {
  todos: [
    { id: 1, text: '學習 React', completed: false },
    { id: 2, text: '完成作業', completed: false },
  ],
}

// 使用 createSlice 創建 todoSlice
const todoSlice = createSlice({
  name: 'todos',
  initialState,
  reducers: {
    addTodo: (state, action) => {
      state.todos.push({ id: Date.now(), text: action.payload, completed: false })
    },
    toggleComplete: (state, action) => {
      const todo = state.todos.find(todo => todo.id === action.payload)
      if (todo) {
        todo.completed = !todo.completed
      }
    },
    deleteTodo: (state, action) => {
      state.todos = state.todos.filter(todo => todo.id !== action.payload)
    },
  },
})

// 將 action 和 reducer 導出
export const { addTodo, toggleComplete, deleteTodo } = todoSlice.actions
export default todoSlice.reducer

3. 設置 Redux Store

使用 configureStore 來設定 store,這會自動幫你加入 Redux DevTools 及 middleware。

// store.js
import { configureStore } from '@reduxjs/toolkit'
import todoReducer from './reducers/todoSlice'

// 創建 Redux store
const store = configureStore({
  reducer: {
    todos: todoReducer,
  },
})

export default store

4. 在 React 中連接 Redux Store

將 Redux store 提供給應用的組件:

// index.js
import React from 'react'
import ReactDOM from 'react-dom'
import { Provider } from 'react-redux'
import App from './App'
import store from './store'

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
)

5. 使用 useSelectoruseDispatch 在 React 中操作 Redux 狀態

可以使用 useSelector 來取得 store 的狀態,使用 useDispatch 來發送 action:

import { useSelector, useDispatch } from "react-redux";
import { addTodo, toggleComplete, deleteTodo } from "./reducers/todoSlice";

  // 使用 useSelector 取得 todos 狀態
  const todos = useSelector((state) => state.todos.todos);

  // 使用 useDispatch 發送 action
  const dispatch = useDispatch();

  // 定義處理函式,使用 Redux Toolkit 的 action creators
  const handleAddTodo = (text) => {
    dispatch(addTodo(text));
  };

  const handleToggleComplete = (id) => {
    dispatch(toggleComplete(id));
  };

  const handleDeleteTodo = (id) => {
    dispatch(deleteTodo(id));
  };

透過使用 Redux Toolkit,我們能夠簡化 Redux 的使用方式:

  • createSlice 幫助我們同時定義 action 和 reducer,避免撰寫重複的程式碼。
  • configureStore 簡化了 store 的設定。
  • 使用 useSelectoruseDispatch 來操作 store,讓程式碼變得更簡潔可讀。

這樣就完成了從傳統 Redux 到 Redux Toolkit 的轉換。

完整程式碼:App.js - nodebox - CodeSandbox

總結

這篇文章介紹了如何使用 Redux Toolkit 來簡化 React 應用中的狀態管理,通過 configureStorecreateSlice,我們可以更輕鬆地處理邏輯,並減少樣板程式碼的撰寫。再透過從傳統 Redux 到 Redux Toolkit 的轉換。最後可以試著玩看看 Redux DevTools 工具,並試著用這工具抓Bug吧!


上一篇
React Redux 實作- Day 29
下一篇
結語 與 目錄 - Day 31
系列文
現在就學React.js 31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言